home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / TPFAST40.ARJ / TPFSTR.ASM < prev    next >
Assembly Source File  |  1991-11-14  |  52KB  |  938 lines

  1. ;   _______________________________________________________________
  2. ;  |                                                               |
  3. ;  |            CopyRight (c) 1989,1990  Steven Lutrov             |
  4. ;  |_______________________________________________________________|____
  5. ;  |                                                               |    |
  6. ;  |  program title : faststr.asm                                  |    | ___
  7. ;  |  author        : Steven Lutrov                                |    |    |
  8. ;  |  revision      : 4.00                                         |    |    |
  9. ;  |  date          : 1991-11-01                                   |    |    |
  10. ;  |  language      : turbo assembler                              |    |    |
  11. ;  |                                                               |    |    |
  12. ;  |  description   : assembly functions for string manipulation.  |    |    |
  13. ;  |                : tested on turbo pascal 5.0 & 5.5             |    |    |
  14. ;  |                                                               |    |    |
  15. ;  |_______________________________________________________________|    |    |
  16. ;      |                                                                |    |
  17. ;      |________________________________________________________________|    |
  18. ;          |                                                                 |
  19. ;          |_________________________________________________________________|
  20. ;
  21.  
  22.  
  23. code    segment word  public
  24.  
  25. assume  cs:code,ds:data
  26.  
  27. public  changechar,compare,stringend,deletechar,deleteleft,deleteright
  28. public  leftend,lowercase,overwrite,padcentre,padends,padleft,padright
  29. public  replace,rightend,seekstring,stringof,uppercase,wordcount
  30.  
  31.  
  32. ;-------------------------------------------------------------------------------
  33. ;procedure changechar(var strx: stype; search,replace :char);
  34. ;-------------------------------------------------------------------------------
  35. ;
  36. data    segment
  37.         extrn  TPFError :byte
  38. data    ends
  39. ;
  40. ;
  41. changechar proc far
  42.                 push bp                         ;save bp
  43.                 mov  bp,sp                      ;set up stack frame
  44.                 mov  TPFError,0                ;assume char found
  45.                 les  di,dword ptr[bp+10]        ;es:di pts to strx
  46.                 sub  dx,dx                      ;flags that a char found
  47.                 mov  al,[bp+6]                  ;get replacement char
  48.                 mov  ah,[bp+8]                  ;search character
  49.                 sub  cx,cx                      ;clear cx
  50.                 mov  cl,es:[di]                 ;get string length
  51.                 jcxz changechar3                ;quit if null string
  52. changechar1:    inc  di                         ;forward string ptr
  53.                 cmp  es:[di],ah                 ;search char?
  54.                 jne  changechar2                ;jump ahead if not
  55.                 mov  es:[di],al                 ;else change char
  56.                 inc  dx                         ;flag that a char found
  57. changechar2:    loop changechar1                ;go do next char
  58.                 or   dx,dx                      ;test if char found
  59.                 jnz  changechar4                ;jump ahead if so
  60. changechar3:    inc  TPFError                  ;else 1 = char not found
  61. changechar4:    pop  bp                         ;restore bp and quit
  62.                 ret  8
  63. changechar endp
  64.  
  65.  
  66. ;-------------------------------------------------------------------------------
  67. ;function compare(strg1,strg2: stype): boolean;
  68. ;-------------------------------------------------------------------------------
  69. ;
  70. compare proc far
  71.                 mov  bx,sp                      ;bx pts to stack
  72.                 push ds                         ;save turbo's ds
  73.                 les  di,ss:dword ptr[bx+8]      ;es:di pts to strg1
  74.                 lds  si,ss:dword ptr[bx+4]      ;ds:si pts to strg2
  75.                 sub  cx,cx                      ;clear cx
  76.                 mov  cl,[si]                    ;get strg2 length
  77.                 cmp  cl,es:[di]                 ;equal to strg1 length?
  78.                 jne  compare6                   ;quit if not
  79.                 jcxz compare5                   ;quit if both null
  80. compare1:       inc  di                         ;forward strg1 ptr
  81.                 inc  si                         ;forward strg2 ptr
  82.                 mov  al,[si]                    ;get strg2 char
  83.                 cmp  al,es:[di]                 ;compare to strg1 char
  84.                 je   compare4                   ;loop if equal
  85.                 cmp  al,122                     ;above lower case vals?
  86.                 ja   compare6                   ;quit if so
  87.                 cmp  al,97                      ;lower case char?
  88.                 jnae compare2                   ;jump ahead if not
  89.                 sub  al,32                      ;make lower case
  90.                 jmp  short compare3             ;go test it
  91. compare2:       cmp  al,90                      ;above upper case vals?
  92.                 ja   compare6                   ;quit if so
  93.                 cmp  al,65                      ;upper case char?
  94.                 jnae compare6                   ;quit if not
  95.                 add  al,32                      ;make lower case
  96. compare3:       cmp  al,es:[di]                 ;compare to strg1 char
  97.                 jne  compare6                   ;quit if not equal
  98. compare4:       loop compare1                   ;go do next char
  99. compare5:       mov  al,1                       ;return true
  100.                 jmp  short compare7             ;jump ahead
  101. compare6:       mov  al,0                       ;return false
  102. compare7:       pop  ds                         ;restore ds and quit
  103.                 ret  8
  104. compare endp
  105.  
  106.  
  107. ;-------------------------------------------------------------------------------
  108. ;function stringend(strx: stype; numberchars :integer): stype;
  109. ;-------------------------------------------------------------------------------
  110. ;
  111. data    segment
  112.         extrn  TPFError :byte
  113. data    ends
  114. ;
  115. ;
  116. stringend proc far
  117.                 push bp                         ;save bp
  118.                 mov  bp,sp                      ;set up stack frame
  119.                 push ds                         ;save ds
  120.                 les  di,dword ptr[bp+12]        ;es:di pts to return strx
  121.                 lds  si,dword ptr[bp+8]         ;ds:si pts to source strx
  122.                 sub  cx,cx                      ;clear cx
  123.                 mov  es:[di],cl                 ;return null string if error
  124.                 mov  cl,[bp+6]                  ;get numberchars (255 max)
  125.                 sub  bx,bx                      ;clear bx
  126.                 mov  bl,[si]                    ;strx length in bx
  127.                 mov  dl,1                       ;1 = null string
  128.                 or   bl,bl                      ;test for null string
  129.                 jz   stringend3                 ;quit routine if null
  130.                 dec  dl                         ;0 = no error
  131.                 cmp  cx,bx                      ;numberchars < length?
  132.                 jbe  stringend1                 ;jump ahead if so
  133.                 mov  cx,bx                      ;else return whole string
  134.                 mov  dl,2                       ;2 = numberchars greater than length
  135. stringend1:     mov  es:[di],cl                 ;return strx descriptor
  136.                 sub  bx,cx                      ;length minus numberchars
  137.                 inc  di                         ;forward return strx ptr to first char
  138.                 inc  si                         ;save for source strx
  139.                 add  si,bx                      ;add starting offset to source
  140. stringend2:     cld                             ;direction forward
  141.                 rep movsb                       ;move the portion of the string
  142. stringend3:     pop  ds                         ;restore ds
  143.                 mov  TPFError,dl               ;set TPFError
  144.                 pop  bp                         ;restore bp and quit
  145.                 ret  6
  146. stringend endp
  147.  
  148.  
  149.  
  150. ;-------------------------------------------------------------------------------
  151. ;procedure deletechar(var strx: stype; ch :char);
  152. ;-------------------------------------------------------------------------------
  153. ;
  154. data    segment
  155.         extrn TPFError :byte
  156. data    ends
  157. ;
  158. ;
  159. ;
  160. deletechar proc far
  161.                 cld                             ;set direction flag
  162.                 mov  TPFError,1                ;1 = char not found
  163.                 push bp                         ;save bp
  164.                 push ds                         ;save ds
  165.                 mov  bp,sp                      ;set up stack frame
  166.                 les  di,dword ptr [bp+10]       ;get string address
  167.                 mov  al,[bp+8]                  ;get char to delete
  168.                 sub  bp,bp                      ;use bp as TPFError flag
  169.                 push es                         ;push es...
  170.                 pop  ds                         ;...then copy into ds
  171.                 mov  bx,di                      ;bx will pt to descriptor
  172.                 sub  cx,cx                      ;clear cx
  173.                 mov  cl,es:[di]                 ;get string length
  174.                 jcxz deletechar3                ;quit if null string
  175.                 inc  di                         ;pt di to start of string
  176.                 mov  si,di                      ;copy into si
  177.                 cld                             ;direction forward in movsb
  178. deletechar1:    cmp  [si],al                    ;check for the character
  179.                 je   deletechar2                ;jump if char found
  180.                 movsb                           ;move the char
  181.                 loop deletechar1                ;go check next char
  182.                 jmp  short deletechar3          ;finished
  183. deletechar2:    inc  si                         ;forward source ptr
  184.                 dec  byte ptr[bx]               ;decrease string descriptor
  185.                 inc  bp                         ;flag that char found
  186.                 loop deletechar1                ;go check next char
  187. deletechar3:    pop  ds                         ;restore ds
  188.                 or   bp,bp                      ;test bp for zero
  189.                 jz   deletechar4                ;jump if no match found
  190.                 dec  TPFError                  ;else TPFError = 0
  191. deletechar4:    pop  bp                         ;restore bp and quit
  192.                 ret  6
  193. deletechar endp
  194.  
  195.  
  196. ;-------------------------------------------------------------------------------
  197. ;procedure deleteleft(var strx: stype; border :char);
  198. ;-------------------------------------------------------------------------------
  199. ;
  200. data    segment
  201.         extrn  TPFError :byte
  202. data    ends
  203. ;
  204. ;
  205. deleteleft proc far
  206.                 mov  TPFError,0                ;assume no error
  207.                 push ds                         ;ds is changed
  208.                 push bp                         ;save bp
  209.                 mov  bp,sp                      ;set up stack frame
  210.                 les  di,dword ptr [bp+10]       ;es:di pts to string
  211.                 lds  si,dword ptr [bp+10]       ;so does ds:si
  212.                 mov  si,di                      ;keep si at descriptor
  213.                 mov  al,[bp+8]                  ;get the border character
  214.                 pop  bp                         ;restore bp
  215.                 sub  cx,cx                      ;clear cx
  216.                 mov  cl,es:[di]                 ;string length in cx
  217.                 jcxz deleteleft1                ;quit if null
  218.                 mov  bx,cx                      ;copy of string length in bx
  219.                 inc  di                         ;pt to first byte of string
  220.                 cld                             ;direction forward
  221.                 repne scasb                     ;look for the border character
  222.                 jnz  deleteleft1                ;quit if can't find char
  223.                 mov  dx,di                      ;copy of di to dx
  224.                 dec  dx                         ;point to char before
  225.                 sub  dx,si                      ;number characters to delete
  226.                 dec  dx                         ;don't delete border char
  227.                 mov  cx,bx                      ;old string length
  228.                 sub  cx,dx                      ;new string length
  229.                 mov  [si],cl                    ;set new string length
  230.                 inc  si                         ;point si to start of string
  231.                 xchg di,si                      ;reverse pointers for movsb
  232.                 dec  si                         ;don't remove border char
  233.                 rep movsb                       ;move the characters
  234.                 pop  ds                         ;restore ds
  235.                 ret  6                          ;quit
  236. deleteleft1:    pop  ds                         ;---error case:
  237.                 inc  TPFError                  ;1 = null string or char not found
  238.                 ret  6                          ;quit
  239. deleteleft endp
  240.  
  241.  
  242.  
  243. ;-------------------------------------------------------------------------------
  244. ;procedure deleteright(var strx: stype; border :char);
  245. ;-------------------------------------------------------------------------------
  246. ;
  247. data    segment
  248.         extrn  TPFError :byte
  249. data    ends
  250. ;
  251. ;
  252. deleteright proc far
  253.                 push bp                         ;save bp
  254.                 mov  bp,sp                      ;set up stack frame
  255.                 les  di,dword ptr [bp+8]        ;load string address
  256.                 mov  si,di                      ;keep si at descriptor
  257.                 mov  al,[bp+6]                  ;get the border character
  258.                 sub  cx,cx                      ;clear cx
  259.                 mov  TPFError,1                ;1 = null string
  260.                 mov  cl,es:[di]                 ;string length in cx
  261.                 jcxz deleteright3               ;quit if null
  262.                 add  di,cx                      ;point di to end of string
  263. deleteright1:   cmp  [di],al                    ;test for the border char
  264.                 je   deleteright2               ;if found, jump ahead
  265.                 dec  di                         ;else, point to next char
  266.                 loop deleteright1               ;go test next char
  267.                 jmp  short deleteright3         ;char not found
  268. deleteright2:   mov  es:[si],cl                 ;set new string length
  269.                 dec  TPFError                  ;no error
  270. deleteright3:   pop  bp                         ;restore bp and quit
  271.                 ret  6
  272. deleteright endp
  273.  
  274.  
  275.  
  276.  
  277. ;-------------------------------------------------------------------------------
  278. ;function leftend(var strx: stype; border :char): stype;
  279. ;-------------------------------------------------------------------------------
  280. ;
  281. data    segment
  282.         extrn  TPFError :byte
  283. data    ends
  284. ;
  285. ;
  286. leftend proc far
  287.                 mov  dl,1                       ;1 = border char not found
  288.                 push bp                         ;save bp
  289.                 mov  bp,sp                      ;set up stack frame
  290.                 push ds                         ;save ds
  291.                 les  di,dword ptr[bp+8]         ;es:di pts to strx
  292.                 sub  cx,cx                      ;clear cx
  293.                 mov  cl,es:[di]                 ;string length to cx
  294.                 jcxz leftend2                   ;quit if zero
  295.                 inc  di                         ;pt to 1st byte of strx
  296.                 mov  bx,di                      ;copy start position
  297.                 cld                             ;direction forward
  298.                 mov  al,[bp+6]                  ;border character
  299.                 repne scasb                     ;search for the character
  300.                 jnz  leftend1                   ;not found, skip ptr dec
  301.                 dec  di                         ;pull back ptr
  302.                 dec  dl                         ;TPFError = 0, no error
  303. leftend1:       sub  di,bx                      ;distance to char
  304.                 mov  cx,di                      ;use as counter
  305.                 mov  ax,es                      ;transfer es...
  306.                 mov  ds,ax                      ;to ds
  307.                 mov  si,bx                      ;now ds:si pts to start of strx
  308. leftend2:       les  di,dword ptr[bp+12]        ;now es:di pts to return string
  309.                 mov  es:[di],cl                 ;set return descriptor
  310.                 jcxz leftend3                   ;jump ahead if null strx
  311.                 inc  di                         ;forward ptr
  312.                 rep  movsb                      ;move the string
  313. leftend3:       pop  ds                         ;restore ds
  314.                 mov  TPFError,dl               ;set TPFError
  315.                 pop  bp                         ;restore bp and quit
  316.                 ret  6
  317. leftend endp
  318.  
  319.  
  320. ;-------------------------------------------------------------------------------
  321. ;procedure lowercase(var strx: stype);
  322. ;-------------------------------------------------------------------------------
  323. ;
  324. lowercase proc far
  325.                 mov  bx,sp                      ;bx points to stack
  326.                 les  di,ss:dword ptr[bx+4]      ;es:di pts to string
  327.                 sub  cx,cx                      ;clear cx
  328.                 mov  cl,es:[di]                 ;get string length
  329.                 jcxz lowercase3                 ;quit if null
  330. lowercase1:     inc  di                         ;pt to next char of strx
  331.                 cmp  es :byte ptr [di],'Z'      ;test high char
  332.                 ja   lowercase2                 ;skip ahead if above
  333.                 cmp  es :byte ptr [di],'A'      ;test low char
  334.                 jb   lowercase2                 ;skip ahead if below
  335.                 add  es :byte ptr [di],32       ;change the char
  336. lowercase2:     loop lowercase1                 ;go test next character
  337. lowercase3:     ret  4
  338. lowercase endp
  339.  
  340.  
  341. ;-------------------------------------------------------------------------------
  342. ;procedure overwrite(var strx: stype; substrg: stype; position :integer);
  343. ;-------------------------------------------------------------------------------
  344. ;
  345. data    segment
  346.         extrn  TPFError :byte
  347. data    ends
  348. ;
  349. ;
  350. overwrite proc far
  351.                 mov  TPFError,0                ;assume no error
  352.                 push bp                         ;save bp
  353.                 mov  bp,sp                      ;set up stack frame
  354.                 push ds                         ;ds is changed
  355.                 les  di,dword ptr [bp+12]       ;es:di pts to strx
  356.                 mov  bx,di                      ;bx points to strx
  357.                 sub  cx,cx                      ;clear cx
  358.                 mov  cl,[bp+6]                  ;position in cx
  359.                 jcxz overwrite2                 ;quit if zero
  360.                 cmp  cl,es:[di]                 ;is position within strx?
  361.                 ja   overwrite2                 ;quit if not
  362.                 mov  dx,cx                      ;keep for error check
  363.                 add  di,cx                      ;add to string ptr
  364.                 lds  si,dword ptr [bp+8]        ;ds:si pts to substring
  365.                 mov  cl,[si]                    ;get the string descriptor
  366.                 jcxz overwrite2                 ;quit if null
  367.                 add  dx,cx                      ;dx = substr endchar + 1
  368.                 sub  dl,es:[bx]                 ;subtract string length
  369.                 cmp  dl,1                       ;will substring fit?
  370.                 jg   overwrite3                 ;if not, quit routine
  371. overwrite1:     inc  si                         ;pt to next substrg char
  372.                 mov  dl,[si]                    ;get the char
  373.                 mov  es:[di],dl                 ;insert into the string
  374.                 inc  di                         ;pt to next char of strx
  375.                 loop overwrite1                 ;go do next character
  376.                 pop  ds                         ;restore ds
  377.                 jmp  short overwrite5           ;terminate without error
  378. overwrite2:     mov  al,1                       ;1 = position not in string
  379.                 jmp  short overwrite4           ;jump ahead
  380. overwrite3:     mov  al,2                       ;2 = substring won't fit
  381. overwrite4:     pop  ds                         ;restore ds
  382.                 mov  TPFError,al               ;set TPFError
  383. overwrite5:     pop  bp                         ;restore bp and quit
  384.                 ret  10
  385. overwrite endp
  386.  
  387.  
  388. ;-------------------------------------------------------------------------------
  389. ;procedure padcentre(var strx: stype; ch :char; position,length :integer);
  390. ;-------------------------------------------------------------------------------
  391. ;
  392. data    segment
  393.         extrn  TPFError :byte
  394. data    ends
  395. ;
  396. ;
  397. padcentre proc far
  398.                 push bp                         ;save bp
  399.                 mov  bp,sp                      ;set up stack frame
  400.                 mov  TPFError,1                ;1 = error
  401.                 les  di,dword ptr[bp+12]        ;es:di pts to strx
  402.                 mov  si,di                      ;copy in si
  403.                 sub  dx,dx                      ;clear dx
  404.                 mov  dl,[bp+6]                  ;new strx length in dx (255 max)
  405.                 or   dx,dx                      ;test for zero length
  406.                 jz   padcentre6                 ;quit if zero
  407.                 mov  bx,dx                      ;copy of length in bx
  408.                 sub  cx,cx                      ;clear cx
  409.                 mov  cl,es:[di]                 ;get current strx length
  410.                 cmp  cx,dx                      ;compare to new length
  411.                 jae  padcentre6                 ;quit if longer
  412.                 mov  es:[di],dl                 ;set new strx length
  413.                 sub  dx,cx                      ;dx = number pad chars
  414.                 sub  ax,ax                      ;clear ax
  415.                 mov  al,[bp+8]                  ;get position
  416.                 or   ax,ax                      ;test for 0
  417.                 jnz  padcentre1                 ;jump if not 0
  418.                 inc  ax                         ;else make 1
  419. padcentre1:     cmp  ax,cx                      ;past end of string?
  420.                 jna  padcentre2                 ;jump ahead if not
  421.                 add  di,cx                      ;offset to end of strx
  422.                 jmp  short padcentre4           ;go write pad chars
  423. padcentre2:     add  si,bx                      ;add to target
  424.                 add  di,bx                      ;add to source
  425.                 sub  di,dx                      ;source minus number pad chars
  426.                 sub  cx,ax                      ;subtract from strx len
  427.                 inc  cx                         ;ax pts from 0, adjust
  428. padcentre3:     mov  al,es:[di]                 ;get a char
  429.                 mov  es:[si],al                 ;shift it upwards
  430.                 dec  di                         ;pull back source ptr
  431.                 dec  si                         ;target ptr too
  432.                 loop padcentre3                 ;do next char
  433. padcentre4:     mov  cx,dx                      ;number pad characters
  434.                 mov  al,[bp+10]                 ;get pad character
  435. padcentre5:     inc  di                         ;forward ptr
  436.                 mov  es:[di],al                 ;write pad character
  437.                 loop padcentre5                 ;go do the next
  438.                 dec  TPFError                  ;0 = no error
  439. padcentre6:     pop  bp                         ;restore bp and quit
  440.                 ret  10
  441. padcentre endp
  442.  
  443.  
  444. ;-------------------------------------------------------------------------------
  445. ;procedure padends(var strx: stype; ch :char; length :integer);
  446. ;-------------------------------------------------------------------------------
  447. ;
  448. data    segment
  449.         extrn  TPFError :byte
  450. data    ends
  451. ;
  452. ;
  453. padends proc far
  454.                 push bp                         ;save bp
  455.                 mov  bp,sp                      ;set up stack frame
  456.                 mov  TPFError,1                ;1 = error
  457.                 les  di,dword ptr[bp+10]        ;es:di pts to strx
  458.                 mov  si,di                      ;copy in si
  459.                 sub  dx,dx                      ;clear dx
  460.                 mov  dl,[bp+6]                  ;new strx length in dx
  461.                 or   dx,dx                      ;test for zero length
  462.                 jz   padends7                   ;quit if zero
  463.                 sub  cx,cx                      ;clear cx
  464.                 mov  cl,es:[di]                 ;get strx length
  465.                 cmp  cx,dx                      ;is strx gt new length
  466.                 jae  padends7                   ;quit if true
  467.                 mov  es:[di],dl                 ;set new strx length
  468.                 push di                         ;copy of start of string
  469.                 sub  dx,cx                      ;dx = number pad chars
  470.                 mov  bx,dx                      ;copy to bx
  471.                 shr  bx,1                       ;chars div 2
  472.                 sub  dx,bx                      ;dx is same or 1 larger
  473.                 add  di,cx                      ;pt to end of strx
  474.                 add  si,dx                      ;offset for upward shift
  475.                 add  si,cx                      ;plus string length
  476.                 or   cx,cx                      ;test for null string
  477.                 jnz  padends1                   ;jump ahead if not null
  478.                 sub  bx,bx                      ;
  479.                 mov  bl,[bp+6]                  ;otherwise set at right padding
  480.                 jmp short padends3              ;jump to rightside padding
  481. padends1:       push si                         ;save end position
  482. padends2:       mov  al,es:[di]                 ;get a char
  483.                 mov  es:[si],al                 ;shift it
  484.                 dec  di                         ;dec source ptr
  485.                 dec  si                         ;dec target ptr
  486.                 loop padends2                   ;go do next
  487.                 pop  si                         ;restore end position
  488. padends3:       mov  al,[bp+8]                  ;get the pad char
  489.                 mov  cx,bx                      ;number to pad on right
  490.                 jcxz padends5                   ;jump ahead if zero
  491. padends4:       inc  si                         ;forward ptr
  492.                 mov  es:[si],al                 ;write pad char on right
  493.                 loop padends4                   ;go do next
  494. padends5:       pop  di                         ;di pts to bottom of strx
  495.                 mov  cx,dx                      ;number pad chars on left
  496.                 or   cx,cx                      ;test for zero
  497.                 jz   padends7                   ;quit if zero
  498. padends6:       inc  di                         ;forward ptr
  499.                 mov  es:[di],al                 ;write pad char on left
  500.                 loop padends6                   ;go do next
  501.                 dec  TPFError                  ;0 = no error
  502. padends7:       pop  bp                         ;restore bp and quit
  503.                 ret  8
  504. padends endp
  505.  
  506.  
  507.  
  508. ;-------------------------------------------------------------------------------
  509. ;procedure padleft(var strx: stype; ch :char; length :integer);
  510. ;-------------------------------------------------------------------------------
  511. ;
  512. data    segment
  513.         extrn  TPFError :byte
  514. data    ends
  515. ;
  516. ;
  517. padleft proc far
  518.                 push bp                         ;save bp
  519.                 mov  bp,sp                      ;set up stack frame
  520.                 mov  TPFError,1                ;1 = error
  521.                 push ds                         ;save ds
  522.                 les  di,dword ptr[bp+10]        ;get string address
  523.                 push es                         ;push es...
  524.                 pop  ds                         ;...then load into ds
  525.                 sub  cx,cx                      ;clear cx
  526.                 mov  cl,es:[di]                 ;string length in cl
  527.                 mov  bx,[bp+6]                  ;new string length in bl
  528.                 dec  bx                         ;dec bx for test
  529.                 cmp  bx,254                     ;in range?
  530.                 ja   padleft2                   ;quit if not
  531.                 inc  bx                         ;readjust
  532.                 cmp  cl,bl                      ;compare the two lengths
  533.                 jae  padleft2                   ;quit if old len >= new
  534.                 mov  es:[di],bl                 ;set new string length
  535.                 mov  si,di                      ;pt si to descriptor
  536.                 add  si,cx                      ;now pt si to string end
  537.                 add  di,bx                      ;pt di to new string end
  538.                 sub  bx,cx                      ;number of spaces to pad
  539.                 std                             ;set direction flag
  540.                 rep  movsb                      ;move old string right
  541.                 mov  cx,bx                      ;spaces to pad in cx
  542.                 mov  al,[bp+8]                  ;get pad character
  543. padleft1:       mov  [di],al                    ;insert pad char
  544.                 dec  di                         ;move to next position
  545.                 loop padleft1                   ;go do next char
  546.                 pop  ds                         ;restore ds
  547.                 dec  TPFError                  ;0 = no error
  548.                 jmp  short padleft3             ;jump ahead and quit
  549. padleft2:       pop  ds                         ;exit with error
  550. padleft3:       pop  bp                         ;restore bp and quit
  551.                 ret  8
  552. padleft endp
  553.  
  554.  
  555.  
  556. ;-------------------------------------------------------------------------------
  557. ;procedure padright(var strx: stype; ch :char; length :integer);
  558. ;-------------------------------------------------------------------------------
  559. ;
  560. data    segment
  561.         extrn  TPFError :byte
  562. data    ends
  563. ;
  564. ;
  565. padright proc far
  566.                 push bp                         ;save bp
  567.                 mov  bp,sp                      ;set up stack frame
  568.                 mov  TPFError,1                ;1 = error
  569.                 les  di,dword ptr[bp+10]        ;get string address
  570.                 sub  cx,cx                      ;clear cx
  571.                 mov  cl,es:[di]                 ;string length in cl
  572.                 mov  bx,[bp+6]                  ;new string length
  573.                 dec  bx                         ;dec bx for test
  574.                 cmp  bx,254                     ;in range?
  575.                 ja   padright2                  ;quit if not
  576.                 inc  bx                         ;readjust
  577.                 cmp  cl,bl                      ;compare the two lengths
  578.                 jae  padright2                  ;quit if old len>=new len
  579.                 mov  es:[di],bl                 ;set new string length
  580.                 add  di,cx                      ;point di to end of strx
  581.                 sub  bx,cx                      ;sub old len from new len
  582.                 mov  cx,bx                      ;use as counter
  583.                 mov  al,[bp+8]                  ;get pad character
  584. padright1:      inc  di                         ;increment pointer
  585.                 mov  es:[di],al                 ;insert a pad char
  586.                 loop padright1                  ;go do next char
  587.                 dec  TPFError                  ;0 = no error
  588. padright2:      pop  bp                         ;restore bp and quit
  589.                 ret  8
  590. padright endp
  591.  
  592.  
  593. ;-------------------------------------------------------------------------------
  594. ;procedure replace(var strx: stype; substrg: stype; position,chars :integer);
  595. ;-------------------------------------------------------------------------------
  596. ;
  597. data    segment
  598.         extrn  TPFError :byte
  599. data    ends
  600. ;
  601. ;
  602. replace proc far
  603.                 push bp                         ;save bp
  604.                 mov  bp,sp                      ;set up stack frame
  605.                 push ds                         ;save ds too
  606.                 mov  TPFError,1                ;1 = error has occured
  607.                 les  di,dword ptr[bp+14]        ;es:di pts to strx
  608.                 sub  cx,cx                      ;clear cx
  609.                 mov  byte ptr[bp+7],cl          ;use byte as if word
  610.                 mov  cl,es:[di]                 ;get strx length
  611.                 or   cx,cx                      ;test for null string
  612.                 jnz  replace2                   ;jump ahead if not
  613. replace1:       jmp  replace9                   ;else quit routine
  614. replace2:       sub  bx,bx                      ;clear bx
  615.                 mov  bl,[bp+8]                  ;position to bx
  616.                 or   bx,bx                      ;position 0?
  617.                 jz   replace1                   ;quit if zero
  618.                 cmp  bx,cx                      ;within strx?
  619.                 jnbe replace1                   ;quit if not
  620.                 lds  si,dword ptr[bp+10]        ;ds:si pts to substrg
  621.                 sub  dx,dx                      ;clear dx
  622.                 mov  dl,[si]                    ;substring length
  623.                 or   dx,dx                      ;test for null
  624.                 jz   replace1                   ;quit if null
  625.                 mov  ax,cx                      ;strx length
  626.                 sub  ax,bx                      ;minus position
  627.                 inc  ax                         ;number deletable chars
  628.                 cmp  ax,[bp+6]                  ;cmp to num chars to del
  629.                 jb   replace9                   ;quit if not enough chars
  630.                 mov  ax,[bp+6]                  ;chars to delete
  631.                 cmp  ax,dx                      ;num chars del/replace
  632.                 ja   replace3                   ;must shift chars down
  633.                 jb   replace5                   ;must shift chars up
  634.                 add  di,bx                      ;no shift, di to overlay
  635.                 jmp  short replace7             ;no write substring
  636. replace3:       sub  ax,dx                      ;strx shortened this much
  637.                 sub  cx,ax                      ;new string length
  638.                 mov  es:[di],cl                 ;set descriptor
  639.                 add  di,bx                      ;pt to substrg position
  640.                 mov  si,di                      ;copy to si
  641.                 add  si,dx                      ;pt to end of substrg + 1
  642.                 sub  cx,bx                      ;chars following substrg
  643.                 inc  cx                         ;adjust
  644.                 mov  bx,si                      ;end of substring pos
  645.                 add  bx,ax                      ;forward to shift point
  646. replace4:       mov  al,es:[bx]                 ;get a char
  647.                 mov  es:[si],al                 ;move it downward
  648.                 inc  si                         ;inc target ptr
  649.                 inc  bx                         ;inc source ptr
  650.                 loop replace4                   ;loop till finished
  651.                 jmp  short replace7             ;go write substring
  652. replace5:       neg  ax                         ;dx minus ax in ax
  653.                 add  ax,dx                      ;ax = increased strx len
  654.                 add  cx,ax                      ;new length
  655.                 mov  es:[di],cl                 ;set descriptor
  656.                 mov  si,di                      ;si pts to start of strx
  657.                 add  di,bx                      ;point di to substrg pos
  658.                 add  si,cx                      ;si pts to end of strx
  659.                 mov  bx,si                      ;copy to bx
  660.                 sub  bx,ax                      ;move to shift point
  661.                 sub  cx,[bp+8]                  ;length minus position
  662.                 dec  cx                         ;adjust
  663.                 jcxz replace7                   ;boundary case
  664. replace6:       mov  al,es:[bx]                 ;get a character
  665.                 mov  es:[si],al                 ;move it upwards
  666.                 dec  si                         ;dec target ptr
  667.                 dec  bx                         ;get source ptr
  668.                 loop replace6                   ;loop till finished
  669. replace7:       lds  si,dword ptr[bp+10]        ;point ds:si back to substrg
  670.                 inc  si                         ;forward si to first char
  671. replace8:       mov  cl,[si]                    ;get char from substring
  672.                 mov  es:[di],cl                 ;move to strx
  673.                 inc  si                         ;forward source ptr
  674.                 inc  di                         ;forward target ptr
  675.                 dec  dx                         ;dec substring ctr
  676.                 jnz  replace8                   ;loop till finished
  677.                 pop  ds                         ;restore ds
  678.                 dec  TPFError                  ;0 = no error
  679.                 jmp  short replace10            ;jump ahead
  680. replace9:       pop  ds                         ;terminate with error
  681. replace10:      pop  bp                         ;restore bp and quit
  682.                 ret  12
  683. replace endp
  684.  
  685.  
  686. ;-------------------------------------------------------------------------------
  687. ;function rightend(var strx: stype; border :char): stype;
  688. ;-------------------------------------------------------------------------------
  689. ;
  690. data    segment
  691.         extrn  TPFError :byte
  692. data    ends
  693. ;
  694. ;
  695. rightend proc far
  696.                 push bp                         ;save bp
  697.                 mov  bp,sp                      ;set up stack frame
  698.                 push ds                         ;save ds
  699.                 mov  dl,1                       ;1 = border char not found
  700.                 les  di,dword ptr[bp+8]         ;es:di pts to strx
  701.                 sub  cx,cx                      ;clear cx
  702.                 mov  cl,es:[di]                 ;string length to cx
  703.                 jcxz rightend2                  ;quit if zero
  704.                 add  di,cx                      ;pt to last byte of strx
  705.                 mov  si,di                      ;copy start position
  706.                 std                             ;direction flag backward
  707.                 mov  al,[bp+6]                  ;border character
  708.                 repne scasb                     ;search for the character
  709.                 jnz  rightend1                  ;skip inc if not found
  710.                 inc  di                         ;discard border char
  711.                 dec  dl                         ;TPFError = 0, no error
  712. rightend1:      inc  di                         ;step pointer back
  713.                 sub  si,di                      ;figure number characters
  714.                 inc  si                         ;adjust
  715.                 mov  cx,si                      ;use as counter
  716.                 mov  ax,es                      ;transfer es...
  717.                 mov  ds,ax                      ;to ds
  718.                 mov  si,di                      ;ds:si pts to strx
  719. rightend2:      les  di,dword ptr[bp+12]        ;now es:di pts to return string
  720.                 mov  es:[di],cl                 ;set return descriptor
  721.                 jcxz rightend3                  ;jump ahead if null strx
  722.                 inc  di                         ;forward ptr
  723.                 cld                             ;direction flag forward
  724.                 rep  movsb                      ;move the string
  725. rightend3:      pop  ds                         ;restore ds
  726.                 mov  TPFError,dl               ;set TPFError
  727.                 pop  bp                         ;restore bp and quit
  728.                 ret  6
  729. rightend endp
  730.  
  731.  
  732.  
  733.  
  734. ;-------------------------------------------------------------------------------
  735. ;function seekstring(strx,substrg: stype; startpt :integer) :integer;
  736. ;-------------------------------------------------------------------------------
  737. ;
  738. data    segment
  739.         extrn  TPFError :byte
  740. data    ends
  741. ;
  742. ;
  743. seekstring proc far
  744.                 push bp                         ;save bp
  745.                 mov  bp,sp                      ;set up stack frame
  746.                 push ds                         ;save turbo's ds
  747.                 lds  si,dword ptr[bp+12]        ;ds:si pts to strx
  748.                 les  di,dword ptr[bp+8]         ;ds:di pts to substrg
  749.                 sub  cx,cx                      ;clear cx
  750.                 mov  cl,[bp+6]                  ;get startpt
  751.                 mov  bp,1                       ;1 = startpt out of range
  752.                 jcxz seekstring11               ;quit if zero
  753.                 mov  dl,es:[di]                 ;substr length in dl
  754.                 inc  di                         ;di pts 1st chr of substr
  755.                 inc  bp                         ;2 = substrg is null
  756.                 or   dl,dl                      ;substr length non-zero?
  757.                 jnz  seekstring21               ;continue if so
  758. seekstring11:   jmp  seekstring1                ;error: quit routine
  759. seekstring21:   mov  dh,[si]                    ;strx length in dh
  760.                 dec  bp                         ;1 = strx is null
  761.                 or   dh,dh                      ;test for null
  762.                 jz   seekstring11               ;quit if null
  763.                 mov  bl,cl                      ;startpt
  764.                 add  bl,dl                      ;substrg length
  765.                 dec  bl                         ;adjust
  766.                 cmp  bl,dh                      ;compare to strx length
  767.                 ja   seekstring11               ;quit if out of range
  768.                 mov  bp,0                       ;0 = no error
  769.                 mov  bl,cl                      ;startpt to pos counter
  770.                 dec  bl                         ;adjust
  771.                 sub  dh,cl                      ;sub from search len
  772.                 inc  dh                         ;adjust
  773.                 add  si,cx                      ;begin search at startpt
  774. seekstring31:   mov  al,es:[di]                 ;get char from of substr
  775.                 mov  ah,al                      ;copy in ah
  776.                 cmp  al,97                      ;low end of lower case
  777.                 jb   seekstring41               ;jump if below
  778.                 cmp  al,122                     ;upper end of lower case
  779.                 ja   seekstring51               ;neither upper nor lower
  780.                 sub  ah,32                      ;make ah upper case
  781.                 jmp  short seekstring51         ;go test both
  782. seekstring41:   cmp  al,65                      ;low end of upper case
  783.                 jb   seekstring51               ;neither upper nor lower
  784.                 cmp  al,90                      ;high end of upper case
  785.                 ja   seekstring51               ;neither upper nor lower
  786.                 add  ah,32                      ;make ah lower case
  787. seekstring51:   inc  bl                         ;inc strx pos counter
  788.                 or   dh,dh                      ;counter = zero?
  789.                 jz   seekstring111              ;quit if so
  790.                 dec  dh                         ;dec length counter
  791.                 mov  bh,[si]                    ;get char from strx
  792.                 cmp  bh,al                      ;test for match
  793.                 je   seekstring61               ;jump if found
  794.                 cmp  bh,ah                      ;2nd test for match
  795.                 je   seekstring61               ;jump if found
  796.                 inc  si                         ;forward strx ptr
  797.                 jmp  short seekstring51         ;go check next char
  798. seekstring61:   cmp  dl,1                       ;single char substring?
  799.                 je   seekstring1                ;if so, not a match
  800.                 sub  cx,cx                      ;clear cx
  801.                 mov  cl,dl                      ;cx = substr length
  802.                 dec  cl                         ;1st char already matched
  803.                 push si                         ;save strx position
  804.                 push di                         ;save substr position
  805. seekstring71:   inc  si                         ;pt to nxt char of strx
  806.                 inc  di                         ;pt to nxt char of substr
  807.                 mov  al,es:[di]                 ;get char from of substr
  808.                 mov  ah,al                      ;copy in ah
  809.                 cmp  al,97                      ;low end of lower case
  810.                 jb   seekstring81               ;jump if below
  811.                 cmp  al,122                     ;upper end of lower case
  812.                 ja   seekstring91               ;neither upper nor lower
  813.                 sub  ah,32                      ;make ah upper case
  814.                 jmp  short seekstring91         ;go test both
  815. seekstring81:   cmp  al,65                      ;low end of upper case
  816.                 jb   seekstring91               ;neither upper nor lower
  817.                 cmp  al,90                      ;high end of upper case
  818.                 ja   seekstring91               ;neither upper nor lower
  819.                 add  ah,32                      ;make ah lower case
  820. seekstring91:   mov  bh,[si]                    ;get char from strx
  821.                 cmp  bh,al                      ;test for match
  822.                 je   seekstring101              ;jump if found
  823.                 cmp  bh,ah                      ;2nd test for match
  824.                 je   seekstring101              ;jump if found
  825.                 pop  di                         ;match not made
  826.                 pop  si                         ;restore prior ptrs
  827.                 inc  si                         ;forward strx ptr
  828.                 jmp  short seekstring31         ;resume search for 1st ch
  829. seekstring101:  loop seekstring71               ;go compare next char
  830.                 pop  di                         ;substring found!
  831.                 pop  si                         ;balance stack
  832.                 jmp  short seekstring1          ;go set return value
  833. seekstring111:  sub  bl,bl                      ;return 0
  834. seekstring1:    sub  bh,bh                      ;return in bl, clear bh
  835.                 mov  ax,bx                      ;set return value
  836.                 pop  ds                         ;restore ds
  837.                 mov  bx,bp                      ;get return value
  838.                 mov  TPFError,bl               ;set TPFError
  839.                 pop  bp                         ;restore bp and quit
  840.                 ret  10
  841. seekstring endp
  842.  
  843.  
  844. ;-------------------------------------------------------------------------------
  845. ;function stringof(substrg: stype; length :integer): stype;
  846. ;-------------------------------------------------------------------------------
  847. ;
  848. data    segment
  849.         extrn TPFError :byte
  850. data    ends
  851. ;
  852. stringof proc far
  853.                 push bp                         ;save bp
  854.                 mov  bp,sp                      ;set up stack frame
  855.                 mov  TPFError,1                ;1 = error
  856.                 push ds                         ;save ds
  857.                 les  di,dword ptr[bp+12]        ;es:di pts to return string
  858.                 lds  si,dword ptr[bp+8]         ;ds:si pts to substring
  859.                 mov  byte ptr es:[di],0         ;return null string if error
  860.                 mov  cx,[bp+6]                  ;return string length
  861.                 jcxz stringof3                  ;quit if null
  862.                 sub  ch,ch                      ;255 max
  863.                 mov  dl,[si]                    ;get substring length
  864.                 mov  dh,dl                      ;copy in dh
  865.                 or   dl,dl                      ;test for zero length
  866.                 jz   stringof3                  ;quit if zero
  867.                 mov  es:[di],cl                 ;set return strx descriptor
  868.                 mov  bx,si                      ;copy strx start point
  869. stringof1:      inc  di                         ;forward ret strx ptr
  870.                 inc  si                         ;forward strx ptr
  871.                 mov  al,[si]                    ;get character
  872.                 mov  es:[di],al                 ;write character
  873.                 dec  cx                         ;finished yet?
  874.                 jz   stringof2                  ;quit if so
  875.                 dec  dl                         ;end of strx yet?
  876.                 jnz  stringof1                  ;loop if not
  877.                 mov  dl,dh                      ;renew strx counter
  878.                 mov  si,bx                      ;si back to start of strx
  879.                 jmp  short stringof1            ;go start strx again
  880. stringof2:      pop  ds                         ;restore ds
  881.                 dec  TPFError                  ;0 = no error
  882.                 jmp  short stringof4            ;jump ahead
  883. stringof3:      pop  ds                         ;terminate with error
  884. stringof4:      pop  bp                         ;restore bp and quit
  885.                 ret  6
  886. stringof endp
  887.  
  888. ;-------------------------------------------------------------------------------
  889. ;procedure uppercase(var strx: stype);
  890. ;-------------------------------------------------------------------------------
  891. ;
  892. uppercase proc far
  893.                 mov  bx,sp                      ;bx points to stack
  894.                 les  di,ss:dword ptr[bx+4]      ;es:di pts to string
  895.                 sub  cx,cx                      ;clear cx
  896.                 mov  cl,es:[di]                 ;get string length
  897.                 jcxz uppercase3                 ;quit if null
  898. uppercase1:     inc  di                         ;pt to next char of strx
  899.                 cmp  es :byte ptr [di],'z'       ;test high char
  900.                 ja   uppercase2                 ;skip ahead if above
  901.                 cmp  es :byte ptr [di],'a'       ;test low char
  902.                 jb   uppercase2                 ;skip ahead if below
  903.                 sub  es :byte ptr [di],32        ;change the char
  904. uppercase2:     loop uppercase1                 ;go test next character
  905. uppercase3:     ret  4
  906. uppercase endp
  907.  
  908. ;=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  909. ;function wordcount(strx: stype) :integer;
  910. ;
  911. ;
  912. wordcount proc far
  913.                 mov  bx,sp                      ;bx points to stack
  914.                 les  di,ss:dword ptr[bx+4]      ;point es:di to string
  915.                 sub  dx,dx                      ;clear dx as counter
  916.                 mov  cx,dx                      ;clear cx
  917.                 mov  cl,es:[di]                 ;get string descriptor
  918.                 mov  al,32                      ;al holds space char
  919. wordcount1:     jcxz wordcount3                 ;jump ahead at eol
  920.                 inc  di                         ;forward pointer
  921.                 dec  cx                         ;dec strx counter
  922.                 cmp  es:[di],al                 ;char a space?
  923.                 je   wordcount1                 ;loop if so
  924.                 inc  dx                         ;word starts -- inc ctr
  925. wordcount2:     jcxz wordcount3                 ;jump ahead at eol
  926.                 inc  di                         ;forward pointer
  927.                 dec  cx                         ;dec strx counter
  928.                 cmp  es:[di],al                 ;char a space?
  929.                 je   wordcount1                 ;back to spc loop if so
  930.                 jmp  short wordcount2           ;else next word char
  931. wordcount3:     mov  ax,dx                      ;set return value
  932.                 ret  4
  933. wordcount endp
  934.  
  935.  
  936. code    ends
  937.         end
  938.